#pragma once

#include "Widgets/Widget.h"
#include "Containers/ScriptDelegateImplement.h" 
#include "Font/StaticTextArranger.h"
#include "CanvasWidget.m.h"

class CRenderCanvasWidget;
class CCanvasItem;
class RTexture2D;

RSTRUCT()
struct SColorfulTextColor
{
    ROBJECT

    SColorfulTextColor()=default;

    SColorfulTextColor(int64_t InStartIndex,const SColor& InColor)
        :StartIndex(InStartIndex)
        ,Color(InColor)
    {

    }

    RFIELD()
    int64_t StartIndex;

    RFIELD()
    SColor Color;

    bool operator==(const SColorfulTextColor& Other) const
    {
        return StartIndex==Other.StartIndex && Color==Other.Color;
    }
};


RCLASS()
class WHENGINE_API RCanvasItem: public RObject
{
    ROBJECT
public:
};


RCLASS(ExtraHeader= ["Font/Font.h","Texture/Texture2D.h"])
class WHENGINE_API RCanvasWidget: public RWidget
{
    ROBJECT
public:

    virtual void PaintSelf(uint16_t& InZOrder,const SRect& InClipArea) override;

    RFUNCTION()
    void Clear();

    RFUNCTION()
    void AddItem(TSharedObjectPtr<RCanvasItem> Item);

    RFUNCTION()
    void AddItems(const TVector<TSharedObjectPtr<RCanvasItem>>& InItems);

    RFUNCTION()
    void AddLine(const SVec2& Start,const SVec2& End,float LineWidth,const SColor& Color);
    
    RFUNCTION()
    void AddRect(const SRect& Rect,const SColor& Color);

    //must be clockwise on widget
    RFUNCTION()
    void AddTriangle(const SVec2& P0,const SVec2& P1,const SVec2& P2,const SColor& Color);

    RFUNCTION()
    void AddImage(const SVec2& Position,const SVec2& Size, TSharedObjectPtr<RTexture2D> Texture);

    RFUNCTION()
    void AddText(const SVec2& LeftTopPosition
        , const CString& Text
        , const SColor& TextColor
        ,int64_t FontSize
        ,TSharedObjectPtr<RFont> Font=nullptr
        ,ETextWrapMethod Wrap=ETextWrapMethod::WrapAtLineEnd
    ); 

    RFUNCTION()
    TSharedObjectPtr<RCanvasItem> AddTextWithAlignment(const SRect& TextRect
        , const CString& Text
        , const SColor& TextColor
        ,int64_t FontSize
        ,ETextHorizontalAlignment HorizontalAlignment=ETextHorizontalAlignment::Left
        ,ETextVerticalAlignment VerticalAlignment=ETextVerticalAlignment::Top
        ,TSharedObjectPtr<RFont> Font=nullptr
    );




    RFUNCTION()
    TSharedObjectPtr<RCanvasItem>
        AddColorfulText(const SVec2& LeftTopPosition
        , const CString& Text
        , const TVector<SColorfulTextColor>& Colors
        ,int64_t FontSize
        ,TSharedObjectPtr<RFont> Font=nullptr
    );

    RFUNCTION()
    void AddCircle(const SVec2& Center,float Radius,const SColor& Color);

    //invoked when paint, every frame
    //you can clear former item and  add items in this delegate 
    RFIELD()
    TScriptDelegate<void()> OnPaint;
protected:
    TVector<TSharedObjectPtr<RCanvasItem>> Items;

    TVector<TSharedObjectPtr<RCanvasItem>> LastItems;
};

RCLASS()
class WHENGINE_API RCanvasLineItem: public RCanvasItem
{
    ROBJECT

public:
    RCanvasLineItem()=default;

    void FillData(const SVec2& Start,const SVec2& End,float LineWidth,const SColor& Color);
    
    SVec2 Start;
    SVec2 End;
    float LineWidth;
    SColor Color;
};

RCLASS()
class WHENGINE_API RCanvasTriangleItem: public RCanvasItem
{
    ROBJECT

public:
    RCanvasTriangleItem()=default;

    void FillData(const SVec2& P0,const SVec2& P1,const SVec2& P2,const SColor& Color);

    SVec2 P0;
    SVec2 P1;
    SVec2 P2;
    SColor Color;
};

RCLASS()
class WHENGINE_API RCanvasCircleItem: public RCanvasItem
{
    ROBJECT

public:
    RCanvasCircleItem()=default;

    void FillData(const SVec2& Center,float Radius,const SColor& Color);

    SVec2 Center;
    float Radius;
    SColor Color;
};


RCLASS()
class WHENGINE_API RCanvasImageItem: public RCanvasItem
{
    ROBJECT

public:
    RCanvasImageItem()=default;
    
    void FillData(const SVec2& Position,const SVec2& Size, TSharedObjectPtr<RTexture2D> InTexture);

    SVec2 Position;
    SVec2 Size;

    RFIELD()
    TSharedObjectPtr<RTexture2D> Texture;

};

RCLASS()
class WHENGINE_API RCanvasTextItem: public RCanvasItem
{
    ROBJECT

public:

    RCanvasTextItem()=default;

#ifdef DEBUG
    //用于调试
    CString Text;
#endif

    CStaticTextArranger TextArranger;
    SColor Color;
    SVec2 LeftTopPosition;
};

RCLASS()
class WHENGINE_API RCanvasColorfulTextItem: public RCanvasItem
{
    ROBJECT

public:

    RCanvasColorfulTextItem()=default;

#ifdef DEBUG
    //用于调试
    CString Text;
#endif

    CStaticTextArranger TextArranger;
    TVector<SColor> Colors;
    SVec2 LeftTopPosition;
};